import PSO from "../common/calc/pso";
import CLPSO from "../common/calc/CLPSO-deploy";
import ICLPSO from "../common/calc/ICLPSO-deploy";
import QPSO from "../common/calc/qpso";
import IQPSO from "../common/calc/iqpso";
import CPSO from "../common/calc/cpso";
import BBO from "../common/calc/bbo";
import Vector from "../common/calc/vector";
import Target from "./target";
import TargetNotDisplay from "./targetNotDisplay";
import TargetGrid from "./targetGrid";
import Interferencer from "./interfer";
import deploy_const from "./constant";
import Array from "../common/utils/array_ext"
import Monitor from "./monitor";
import axios from 'axios'
import simulation from './simulation'
import moment from 'moment'
import config from './config'

// 群体类
function Flock(canvas, iteration_sum, targetNum) {
  // 获得绘图对象
  this.canvas = canvas;
  // 获得监控器对象
  this.monitor = new Monitor();
  // 群体最大迭代次数
  //this.iteration_sum = iteration_sum;
  this.iteration_sum = config.iterNum;
  //目标数量
  //this.targetNum=targetNum;
  this.targetNum = config.targetNum;
  // 群体当前迭代次数
  this.iteration = 0;
  // 网格的默认值
  this.grid = null;
  this.grid2 = null;

  // 干扰物列表
  this.inter_list = [];
  // 目标列表
  this.target_list = [];
  // 评估值变化情况
  this.evaluation = [];
  // 采用的算法
  this.algorithm = null;
  this.run = false;  // 模拟器是否开始运行
  this.gbest = {};

  // 算法名称
  //this.method = "";
  //this.method = config.method;

  // 增加网格
  this.addGrid = function (grid) {
    this.grid = grid;
  };
  this.addGrid2 = function (grid) {
    this.grid2 = grid;
  };

  // 删除网格
  this.delGrid = function () {
    if (this.grid != null) {
      // 清空目标分布的文本框
      $("#randomValue").val("");
      // 令轨迹对象为空
      this.grid = null;
    }
  };

  // 增加目标
  this.addTarget = function (target) {
    this.target_list.push(target)
  };

  // 从储存中增加目标
  this.add_targets_from_store = function () {
    // 取得textarea中的值
    let textarea_val = document.getElementById("randomValue").value.trim();
    // 取得localstory中的值
    let local_val = localStorage.getItem(deploy_const.get("目标分布储存位置"));
    // 设定顺序为:1. textarea中的值, 2.localstorage, 3.随机生成
    if (textarea_val.length > 10) {
      this.string_to_targets(textarea_val);
      localStorage.setItem(deploy_const.get("目标分布储存位置"), textarea_val);
    } else if (local_val != null && local_val.length > 10) {
      this.string_to_targets(local_val);
      document.getElementById("randomValue").value = local_val;
    } else {
      this.add_all_targets();
    }
  };

  //fixme
  //this.add_targets_from_store = function () {
  //
  //        this.add_all_targets();
  //
  //};


  /**
   * 根据给定的目标数,一次性随机生成指定目标
   */
  this.add_all_targets = function () {
    this.removeTargetAll();
    //增加指定目标数量
    //let target_num = $("#target_num").val() - 0;

    //let target_num = this.targetNum;
    //for (let i = 0; i < target_num; i++) {
    //  //let rand_x = Math.random() * this.canvas.width;
    //  //let rand_y = Math.random() * this.canvas.height;
    //  let rand_x = 10 + Math.random() * 780;
    //  let rand_y = 10 + Math.random() * 780;
    //  this.addTarget(new Target(rand_x, rand_y))
    //}


    //this.addTarget(new Target(120, 520));
    //this.addTarget(new Target(200, 80));
    //this.addTarget(new Target(440, 360));
    //this.addTarget(new Target(600, 240));
    //this.addTarget(new Target(640, 600));
    //
    //this.addTarget(new Target(160, 400));
    //this.addTarget(new Target(240, 320));
    //this.addTarget(new Target(320, 160));
    //this.addTarget(new Target(480, 480));
    //this.addTarget(new Target(640, 160));


    let size = [81, 81];  // 网格点个数,例如[4,5]
    let row_num = size[0];  // 横排数量
    let column_num = size[1];  // 纵排数量
    let x_piece = 10;
    let y_piece = 10;


    //边界栅栏目标点128个,32个,16个
    for (let i = 0; i < 33; i=i+8) {
      for(let j = 0; j < 33; j=j+8){
        let x_g = 240+y_piece * j;
        let y_g = 240+x_piece * i;
        if(1<=j&&j<=31&&1<=i&&i<=31){
          continue;
        }else{
          this.addTarget(new Target(x_g, y_g));
        }
      }
    }


    //假设只需覆盖栅栏外围区域像素目标点？？？fixme
    //for (let i = 0; i < column_num; i++) {
    //    for(let j = 0; j < row_num; j++){
    //        let x_g = 0+y_piece * j;
    //        let y_g = 0+x_piece * i;
    //        if(24<=j&&j<=56&&24<=i&&i<=56){
    //            continue;
    //        }else{
    //            this.addTarget(new TargetNotDisplay(x_g, y_g));
    //        }
    //    }
    //}


    //区域内所有像素点
    for (let i = 0; i < row_num; i++) {
        for(let j = 0; j < column_num; j++){
            let x_g = y_piece * j;
            let y_g = x_piece * i;
                this.addTarget(new TargetNotDisplay(x_g, y_g));
        }
    }

    //中心指挥所
    //this.addTarget(new Target(440, 460));
    //this.addTarget(new Target(200, 640));
    //this.addTarget(new Target(600, 200));

    //this.addTarget(new Target(200, 640));
    //this.addTarget(new Target(600, 200));


    ////需要覆盖的目标点
    //this.addTarget(new Target(240, 480));
    //this.addTarget(new Target(600, 640));
    //this.addTarget(new Target(640, 120));

    //边界目标点
    // for (let i = 0; i < 33; i++) {
    //     for(let j = 0; j < 33; j++){
    //         let x_g = 240+y_piece * j;
    //         let y_g = 240+x_piece * i;
    //         if(1<=j&&j<=31&&1<=i&&i<=31){
    //             continue;
    //         }else{
    //             this.addTarget(new TargetGrid(x_g, y_g));
    //         }
    //     }
    // }


    ////核心区域像素目标点
    //for (let i = 0; i < 33; i++) {
    //    for(let j = 0; j < 33; j++){
    //        let x_g = 240+y_piece * j;
    //        let y_g = 240+x_piece * i;
    //
    //            this.addTarget(new TargetNotDisplay(x_g, y_g));
    //
    //    }
    //}
    //
    ////外围像素目标点
    //for (let i = 0; i < column_num; i++) {
    //    for(let j = 0; j < row_num; j++){
    //        let x_g = 0+y_piece * j;
    //        let y_g = 0+x_piece * i;
    //        if(24<=j&&j<=56&&24<=i&&i<=56){
    //            continue;
    //        }else{
    //            this.addTarget(new TargetNotDisplay(x_g, y_g));
    //        }
    //    }
    //}

    // 将目标坐标写入textarea
    let targets_position = "";
    for (let c = 0; c < this.target_list.length; c++) {
      targets_position += this.target_list[c].toString();
    }
    document.getElementById("randomValue").value = targets_position;
    localStorage.setItem(deploy_const.get("目标分布储存位置"), targets_position);
  };

  /**
   * 将字符串转换成目标分布
   * @param info 字符串
   */
  this.string_to_targets = function (info) {
    // 首先移除所有目标
    this.removeTargetAll();
    // 将信息进行拆分
    let info_list = info.split("&#");
    let target_num = Math.floor(info_list.length / 2);
    for (let i = 0; i < target_num; i++) {
      let [x, y] = [info_list[i * 2], info_list[i * 2 + 1]];
      this.addTarget(new Target(x, y))
    }
  };

  //删除目标
  this.delTarget = function () {
    this.target_list.pop()
  };

  // 删除所有目标
  this.removeTargetAll = function () {
    this.target_list = [];
  };

  this.addInterfer = function (interfer) {
    this.inter_list.push(interfer);
  };

  this.delInterfer = function () {
    this.inter_list.pop();
  };

  this.removeInterfer = function () {
    while (this.inter_list.length > 0) {
      this.inter_list.pop()
    }
  };

  /**
   * 探测函数
   * @param dis  目标到干扰物的距离
   * @param range  干扰半径
   * @returns {number}  被探测到的系数
   */
  // this.discover_func = function (dis_list, range) {
  //     // 筛选出距离中小于干扰范围的值
  //     dis_list = dis_list.filter(x => x < range);
  //     // 如果筛选出的干扰物没有,则返回1
  //     if (dis_list.length == 0) {
  //         //return 1;//fixme
  //         //这个目标不在干扰物范围内
  //         return -0.4;
  //     } else if (dis_list.length == 1) {
  //         let dis = dis_list[0];
  //         //return (dis * dis) / (range * range);//fixme
  //         //这个目标在1个干扰物范围内
  //         return 0.3;
  //     } else if (dis_list.length > 1) {
  //         let discover_index = 1;
  //
  //         let dis_list_min = Math.min(dis_list.value);
  //         discover_index = discover_index * ((dis_list_min * dis_list_min) / (range * range));
  //
  //         // for (let dis of dis_list) {
  //         //     discover_index = discover_index * ((dis * dis) / (range * range));
  //         // }
  //
  //         //return discover_index;//fixme
  //         //这个目标在多个干扰物范围内
  //         //return 0;
  //
  //     }
  // };

  //fixme 对于每个目标而言，需要满足k覆盖
  this.recover_func1 = function (dis_list, range, life) {
    // 筛选出距离中小于干扰范围的值
    dis_list = dis_list.filter(x => x < range);
    // 如果该目标未k覆盖,
    if (dis_list.length < 2) {  //3 fixme

      life.push(0);
      return -10;
    }
    else {

      life.push(dis_list.length);
      return 0;
    }
  };

  //this.recover_func2 = function (dis_list, range) {
  //    // 筛选出距离中小于范围的值
  //    dis_list = dis_list.filter(x => x < range);
  //    // 如果该传感器未覆盖目标,则返回0
  //    if (dis_list.length == 0) {
  //        return 0;
  //    } else {
  //        return dis_list.length;
  //    }
  //};


  // fixme 评估函数,每个目标点都需要至少k个传感器
  this.evaluate = solution => {
    // 所有目标的被发现系数
    let discover_index1 = 0;//[]
    let discover_index2 = 0;
    let len = solution.length;
    // 干扰器个数
    let inter_num = Math.floor(len / 2);
    // 干扰器范围
    let inter_range = document.getElementById("inter_range").value - 0;
    // 所有干扰器坐标的列表
    let interPos_list = [];
    for (let i = 0; i < inter_num; i++) {
      let inter = new Interferencer(solution[2 * i], solution[2 * i + 1], inter_range);
      interPos_list.push(inter.pos);
    }

    //k覆盖的网络寿命等价如下?生成每个目标点到传感器的距离map，对于每个传感器而言，如果覆盖了目标点则进行评价
    //let targetPos_list = [];
    //for (let j = 0; j < this.targetNum; j++) {
    //  targetPos_list.push(this.target_list[j].pos);
    //}
    //for (let i = 0; i < inter_num; i++) {
    //  let dis_list = targetPos_list.map(x => x.euc2d(inter_list[i].pos));
    //  discover_index1.push(this.recover_func1(dis_list, inter_range));
    //
    //}

    //fixme k覆盖的寿命
    let punish = 0;
    let life = [];
    for (let c = 0; c < this.targetNum; c++) {
      let dis_list = interPos_list.map(x => x.euc2d(this.target_list[c].pos));
      //discover_index1 += this.recover_func1(dis_list, inter_range);
      punish += this.recover_func1(dis_list, inter_range, life);
      //console.log(punish);
    }

    //fixme 评价像素点的覆盖率
    for (let j = this.targetNum; j < this.target_list.length; j++) {
      let dis_list2 = [];
      let cover = 0;
      for (let i = 0; i < inter_num; i++) {
        //let dis_list1 = inter_pos.map(x => x.euc2d(this.target_list[j].pos));
        dis_list2.push(interPos_list[i].euc2d(this.target_list[j].pos));
        //discover_index1 += this.evaluateCover1(dis_list1, inter_list[i].range);
        if (dis_list2[i] <= inter_range) {
          cover = 1;
          break;
        }
      }
      discover_index2 += cover;
    }

    //最早的评价方法
    // for (let target of this.target_list) {
    //     // 获得目标到干扰物的最近距离
    //     let target_pos = target.pos;
    //     // 获得每个干扰物到目标的距离
    //     let dis_list = inter_list.map(x => x.euc2d(target_pos));
    //     // 将单个目标被发现的系数累加到总系数中
    //     discover_index += this.discover_func(dis_list, inter_range);
    // }

    life=life.filter(value => value > 0);
    const lifeTime = life.sort((a, b) => a - b)[0]*100;
    //fixme 以下为寿命指标、覆盖指标 和 k覆盖约束指标
    const lifeIndex=1-3/lifeTime;
    const disIndex=discover_index2/6561;
    const punishIndex=punish/25;
    //return (-1) * (punish+lifeTime);
    return (-1) * (punish+disIndex);

    //fixme
    //let lifeTime = discover_index1.filter(function(item) {
    //  return item != 0
    //});

    //const lifeTime = discover_index1.filter(value => value > 0);
    //lifeTime.sort((a, b) => a - b);
    //return (-1) * (lifeTime[0] + discover_index2/6561);

    //discover_index1.forEach(function(item, index, discover_index1) {
    //  if(item === 0) {
    //    discover_index1.splice(index, 1);
    //  }
    //});
    //discover_index1.sort((a, b) => a - b);
    //return (-1) * (discover_index1[0] + discover_index2/6561);

  };



  // fixme 综合覆盖的评估函数,
  this.evaluateCover = solution => {
    // 所有目标的被发现系数
    let discover_index1 = 0;
    let discover_index2 = 0;
    let len = solution.length;
    // 干扰器个数
    let inter_num = Math.floor(len / 2);
    // 干扰器范围
    let inter_range = document.getElementById("inter_range").value - 0;
    // 所有干扰器的列表
    let inter_list = [];
    for (let i = 0; i < inter_num; i++) {
      //let inter = new Vector(solution[2 * i], solution[2 * i + 1]);
      let inter = new Interferencer(solution[2 * i], solution[2 * i + 1], inter_range);
      //let inter = new Interferencer(solution[2 * i], solution[2 * i + 1], inter_range+i*40);
      inter_list.push(inter);
    }

    //fixme 防御效果即覆盖效果，主要可以分为目标点覆盖和像素点覆盖
    //指挥所
    let dis_list0 = [];
    let discover_index0 = -27;

    //每个防御单元只能选择部署在其中的一个指挥所附近
    for (let c = 0; c < 3; c++) {

      //let dis_list1 = inter_pos.map(x => x.euc2d(this.target_list[j].pos));
      dis_list0.push(inter_list[c].pos.euc2d(this.target_list[c].pos));
      //discover_index1 += this.evaluateCover1(dis_list1, inter_list[i].range);
      if (dis_list0[c] <= 100) {
        discover_index0 = discover_index0 + 10;
        //break;

      }
    }



    ////边界目标
    // for (let j = 3; j < 128+3; j++) {
    //核心区域
    for (let j = 0 + 3; j < 1089 + 3; j++) {
      let dis_list1 = [];
      let cover = 0;
      for (let i = 0; i < inter_num; i++) {
        //let dis_list1 = inter_pos.map(x => x.euc2d(this.target_list[j].pos));
        dis_list1.push(inter_list[i].pos.euc2d(this.target_list[j].pos));
        //discover_index1 += this.evaluateCover1(dis_list1, inter_list[i].range);
        if (dis_list1[i] <= inter_list[i].range) {
          cover = 1;
          break;
        }
      }
      discover_index1 += cover;
    }
    ////覆盖边界目标时的外围像素点
    //for (let k = 128+3; k < 5600+3; k++) {
    //覆盖核心区域时的外围像素点
    for (let k = 1089 + 3; k < 6561 + 3; k++) {
      let dis_list2 = [];
      let cover = 0;
      for (let i = 0; i < inter_num; i++) {
        //let dis_list2 = inter_pos.map(x => x.euc2d(this.target_list[k].pos));
        dis_list2.push(inter_list[i].pos.euc2d(this.target_list[k].pos));
        //discover_index2 += this.evaluateCover1(dis_list2, inter_list[i].range);
        if (dis_list2[i] <= inter_list[i].range) {
          cover = 1;
          break;
        }
      }
      discover_index2 += cover;
    }

    //fixme
    //return discover_index;
    //边界目标
    //return (1-discover_index0/3)+(1-(discover_index1+discover_index2)/6561);
    //return 1-(discover_index1+discover_index2)/5600;
    //return 0.6*(1-discover_index1/128)+0.4*(1-discover_index2/5472);
    //return 0.5*(1-discover_index1/1089)+0.3*(1-discover_index2/5472);
    //return 0.9*(1-discover_index1/1089)+0.1*(1-discover_index2/5472);
    //核心区域
    //return 1-(discover_index1+discover_index2)/6561;

  };
  //fixme 对于每个目标点
  this.evaluateCover1 = function (dis_list1, range) {
    // 筛选出距离中小于干扰范围的值
    dis_list1 = dis_list1.filter(x => x < range);
    //if dis_list1
    // 如果该目标覆盖,则返回0
    if (dis_list1.length >= 0) {
      return 0;
    } else {
      return 1;

      // let b = 1;
      // for(let i = 0; i < dis_list1.length; i++){
      //     b = b*(1-Math.E ** (-(dis_list1[i]/range)));
      // }
      //
      // if((1-b)>=0.9){
      //     return 1;
      // }else{
      //     return 0;
      // }

    }
  };
  //fixme 对于每个像素点
  this.evaluateCover2 = function (dis_list2, range) {
    // 筛选出距离中小于干扰范围的值
    dis_list2 = dis_list2.filter(x => x < range);
    // 如果该目标被覆盖,则返回1
    if (dis_list2.length == 0) {
      return 0;
    } else {

      return 1;
    }
  };


  // fixme 暴露率的评估函数
  this.evaluateExposeIndex = (solution) => {
    // 计算单个雷达对目标的隐藏率
    const _calcSoloExposeIndex = (dis, inter_range) => {
      const exposeLevel = 1  // 暴露率参数
      //return Math.E ** (exposeLevel * ((dis/inter_range)-1))
      return 1 - (1 - dis / inter_range) ** 2 //视觉传感器
      //return 1-
    }
    // 计算雷达群对目标的隐藏率
    const _getExposeIndex = (dis_list, interRange) => {
      // 获得所有在雷达有效范围的距离, 求得有效雷达数量
      const inRangeDis = dis_list.filter(dis => dis < interRange)
      const radarNum = inRangeDis.length
      // 如果没有雷达, 则暴露值为0
      if (radarNum === 0) {
        return 100
      } else if (radarNum === 1) {
        // 如果只有一个雷达, 则直接计算
        return _calcSoloExposeIndex(inRangeDis[0], interRange)
      } else if (radarNum > 1) {
        // 如果不止一个雷达, 则找到最近的距离,再进行处理
        inRangeDis.sort((a, b) => a - b)
        // 找到最近的距离
        let nearestRadar = inRangeDis[0]
        inRangeDis.forEach((dis, index) => {
          if (index !== 0) {
            nearestRadar += 1 / (inRangeDis.length - 1) * (interRange - dis)
            //nearestRadar += -dis
          }
        })
        return _calcSoloExposeIndex(nearestRadar, interRange)
      }
    }

    let ExposeNum = 0;  // 总暴露值
    let len = solution.length;
    // 干扰器个数
    let inter_num = Math.floor(len / 2);
    // 干扰器范围
    let interRange = document.getElementById("inter_range").value - 0;
    // 所有干扰器的列表
    let interList = [];
    for (let i = 0; i < inter_num; i++) {
      let inter = new Vector(solution[2 * i], solution[2 * i + 1]);
      interList.push(inter);
    }

    for (let target of this.target_list) {
      // 获得目标到干扰物的最近距离
      let target_pos = target.pos;
      // 获得每个干扰物到目标的距离
      let disList = interList.map(x => x.euc2d(target_pos));
      // 将单个目标被发现的系数累加到总系数中
      ExposeNum += _getExposeIndex(disList, interRange);
    }
    return ExposeNum / this.targetNum;
  }


  //this.setConfig(config){
  //    this.config = config;
  //    this.method = config.method;
  //}

  // 设置算法情况
  this.set_algorithm = function (config) {
    // 干扰物数量
    let inter_num = document.getElementById("inter_num").value - 0;
    let method = config.method;

    if (inter_num > 0) {
      let dimension = inter_num * 2;
      let ub = [this.canvas.width, this.canvas.height].repeat(inter_num);
      let lb = [0, 0].repeat(inter_num);


      if (method === "BBO") {
        console.log("使用BBO算法");
        //this.algorithm = new BBO(dimension, ub, lb, this.evaluateCover, config.particleNum, config.iterNum);
        this.algorithm = new BBO(dimension, ub, lb, this.evaluate, config.particleNum, config.iterNum);
      } else if (method === "PSO") {
        console.log("使用PSO算法");
        //this.algorithm = new PSO(dimension, ub, lb, this.evaluateCover, config.particleNum, config.iterNum);
        this.algorithm = new PSO(dimension, ub, lb, this.evaluate, config.particleNum, config.iterNum);
      } else if (method === "CLPSO") {
        console.log("使用CLPSO算法");
        //this.algorithm = new CLPSO(dimension, ub, lb, this.evaluateExposeIndex, config.particleNum, config.iterNum);
        //evaluateCover
        //this.algorithm = new CLPSO(dimension, ub, lb, this.evaluateCover, config.particleNum, config.iterNum);
        this.algorithm = new CLPSO(dimension, ub, lb, this.evaluate, config.particleNum, config.iterNum);
      }
      else if (method === "ICLPSO") {
        console.log("使用ICLPSO算法");
        this.algorithm = new ICLPSO(dimension, ub, lb, this.evaluate, config.particleNum, config.iterNum);
      }
      else if (method === "QPSO") {
        console.log("使用QPSO算法");
        //this.algorithm = new QPSO(dimension, ub, lb, this.evaluateCover, config.particleNum, config.iterNum);
        this.algorithm = new QPSO(dimension, ub, lb, this.evaluate, config.particleNum, config.iterNum);
      }
      else if (method === "IQPSO") {
        console.log("使用IQPSO算法");
        this.algorithm = new IQPSO(dimension, ub, lb, this.evaluate, config.particleNum, config.iterNum);
      }
      else if (method === "CPSO") {
        console.log("使用CPSO算法");
        let dimension = 2;
        // fixed: 这里维度是2, 但是ub和lb只需要重复1次就行了,不是2次
        let ub = [this.canvas.width, this.canvas.height].repeat(1);
        let lb = [0, 0].repeat(1);
        this.algorithm = new CPSO(config.interNum, dimension, ub, lb, this.evaluate, config.particleNum, config.iterNum);
      }
    }
  };

  // 更新数据方法
  this.update = function () {
    const generateSaveData = () => {
      const saveData = {}
      saveData["saveTime"] = moment().format('YYYY-MM-DD HH:mm:ss')
      //saveData['method'] = this.method
      saveData['gbestValue'] = this.algorithm.gbestValue
      saveData["Distribution"] = this.inter_list
      saveData["config"] = config
      //saveData["targetDistribution"] = this.target_list
      //saveData['gbest'] = this.gbest
      //saveData["evaluation"] = this.evaluation
      //fixme
      saveData["evaluateExposeIndex"] = this.evaluation

      return saveData
    }

    // 初始化计算方法
    if (this.algorithm === null) {
      this.set_algorithm(config);
    }
    // 如果迭代未完成,则每次全局迭代数+1
    if (this.iteration < this.iteration_sum) {
      this.iteration++;
      if (this.iteration % 1 === 0) {
        const { currentStep, gbest, gbestValue } = this.algorithm.step_run(1);
        //const [gbest, gbest_value] = this.algorithm.step_run(50);
        this.set_refer(gbest);
        this.monitor.update_data(-gbestValue, 1);//需要显示gbestValue的相反数?
        this.evaluation.push({ iter: this.iteration, gbestValue: gbestValue.toFixed(3) });
        this.gbest = gbest;
        this.monitor.show();
      }
    } else {
      this.run = false
      axios.post("http://localhost:3001/saveDeploy", {
        id: "测试数据",
        data: JSON.stringify(generateSaveData())
      }).then(
        (response) => {
          setTimeout(function () {
            location.reload();
          }, 5000)
        }
      ).catch((error) => {
        console.log("失败", error)
      })
    }

  };

  /**
   * 根据解的情况绘制干扰物
   * @param solution
   */
  this.set_refer = function (solution) {
    // 清空干扰物
    this.removeInterfer();
    let inter_range = document.getElementById("inter_range").value - 0;
    let len = solution.length;
    //let len = ;
    // 干扰器个数
    let inter_num = Math.floor(len / 2);
    // 所有干扰器的列表
    let inter_list = [];
    for (let i = 0; i < inter_num; i++) {
      //let inter = new Interferencer(solution[2 * i], solution[2 * i + 1], inter_range+i*40);
      let inter = new Interferencer(solution[2 * i], solution[2 * i + 1], inter_range);
      this.addInterfer(inter);
    }
  };

  // 整个群体的绘图方法
  this.draw = function (ctx, width, height) {
    let i;
    let accSpeed = 0;  // 速度的累加值
    let speeds = [];
    // 绘制网格
    if (this.grid !== null) {
      this.grid.draw(ctx);
    }
    if (this.grid2 !== null) {
      this.grid2.draw(ctx);
    }

    //fixme  绘制目标：核心区1089，边界128
    for (let i = 0; i < this.targetNum; i++) {
      this.target_list[i].draw(ctx);
    }
    //  绘制干扰物
    for (let i = 0; i < this.inter_list.length; i++) {
      this.inter_list[i].draw(ctx);
    }
  }
}

export default Flock;